vulkan: Add shader for color drawing with rectangle clip
authorBenjamin Otte <otte@redhat.com>
Sun, 25 Dec 2016 05:01:54 +0000 (06:01 +0100)
committerBenjamin Otte <otte@redhat.com>
Sun, 25 Dec 2016 05:23:12 +0000 (06:23 +0100)
gsk/gskvulkanrender.c
gsk/gskvulkanrenderpass.c
gsk/gskvulkanrenderprivate.h
gsk/resources/vulkan/color-clip.frag.glsl [new file with mode: 0644]
gsk/resources/vulkan/color-clip.frag.spv [new file with mode: 0644]
gsk/resources/vulkan/color-clip.vert.glsl [new file with mode: 0644]
gsk/resources/vulkan/color-clip.vert.spv [new file with mode: 0644]
gsk/resources/vulkan/color.frag.spv

index d23ff8cd3edcc207e5a9b8d5257ca8cf00d226c0..6f57c1d8c909260a371d08e00fd254f747c77f06 100644 (file)
@@ -315,6 +315,7 @@ gsk_vulkan_render_get_pipeline (GskVulkanRender       *self,
   } pipeline_info[GSK_VULKAN_N_PIPELINES] = {
     { "blit", gsk_vulkan_blend_pipeline_new },
     { "color", gsk_vulkan_color_pipeline_new },
+    { "color-clip", gsk_vulkan_color_pipeline_new },
     { "color-clip-rounded", gsk_vulkan_color_pipeline_new }
   };
 
index 21a5cb9c88578c38364a1e93c6ee3e9883f8014e..0721e9a74a4d516ad2f803e51792061ea7fa4f43 100644 (file)
@@ -129,6 +129,8 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass           *self,
     case GSK_COLOR_NODE:
       if (gsk_vulkan_clip_contains_rect (&constants->clip, &node->bounds))
         pipeline_type = GSK_VULKAN_PIPELINE_COLOR;
+      else if (constants->clip.type == GSK_VULKAN_CLIP_RECT)
+        pipeline_type = GSK_VULKAN_PIPELINE_COLOR_CLIP;
       else if (constants->clip.type == GSK_VULKAN_CLIP_ROUNDED_CIRCULAR)
         pipeline_type = GSK_VULKAN_PIPELINE_COLOR_CLIP_ROUNDED;
       else
@@ -551,7 +553,9 @@ gsk_vulkan_render_pass_draw (GskVulkanRenderPass     *self,
 
           for (step = 1; step + i < self->render_ops->len; step++)
             {
-              if (g_array_index (self->render_ops, GskVulkanOp, i + step).type != GSK_VULKAN_OP_COLOR)
+              GskVulkanOp *cmp = &g_array_index (self->render_ops, GskVulkanOp, i + step);
+              if (cmp->type != GSK_VULKAN_OP_COLOR || 
+                  cmp->render.pipeline != current_pipeline)
                 break;
             }
           current_draw_index += gsk_vulkan_color_pipeline_draw (GSK_VULKAN_COLOR_PIPELINE (current_pipeline),
index c5f7379daf6b77ca620cf70b1e430e2f15f9aeee..f707c2a736f9d0cbfbf53ded8548332bd33b4afc 100644 (file)
@@ -12,6 +12,7 @@ G_BEGIN_DECLS
 typedef enum {
   GSK_VULKAN_PIPELINE_BLIT,
   GSK_VULKAN_PIPELINE_COLOR,
+  GSK_VULKAN_PIPELINE_COLOR_CLIP,
   GSK_VULKAN_PIPELINE_COLOR_CLIP_ROUNDED,
   /* add more */
   GSK_VULKAN_N_PIPELINES
diff --git a/gsk/resources/vulkan/color-clip.frag.glsl b/gsk/resources/vulkan/color-clip.frag.glsl
new file mode 100644 (file)
index 0000000..218ee85
--- /dev/null
@@ -0,0 +1,10 @@
+#version 420 core
+
+layout(location = 0) in vec4 inColor;
+
+layout(location = 0) out vec4 color;
+
+void main()
+{
+    color = vec4(inColor.rgb * inColor.a, inColor.a);
+}
diff --git a/gsk/resources/vulkan/color-clip.frag.spv b/gsk/resources/vulkan/color-clip.frag.spv
new file mode 100644 (file)
index 0000000..29bbae9
Binary files /dev/null and b/gsk/resources/vulkan/color-clip.frag.spv differ
diff --git a/gsk/resources/vulkan/color-clip.vert.glsl b/gsk/resources/vulkan/color-clip.vert.glsl
new file mode 100644 (file)
index 0000000..b893217
--- /dev/null
@@ -0,0 +1,42 @@
+#version 420 core
+
+layout(location = 0) in vec4 inRect;
+layout(location = 1) in vec4 inColor;
+
+layout(push_constant) uniform PushConstants {
+    mat4 mvp;
+    vec4 clip_bounds;
+    vec4 clip_widths;
+    vec4 clip_heights;
+} push;
+
+out gl_PerVertex {
+  vec4 gl_Position;
+};
+
+layout(location = 0) out vec4 outColor;
+
+vec2 offsets[6] = { vec2(0.0, 0.0),
+                    vec2(1.0, 0.0),
+                    vec2(0.0, 1.0),
+                    vec2(0.0, 1.0),
+                    vec2(1.0, 0.0),
+                    vec2(1.0, 1.0) };
+
+vec4 intersect(vec4 a, vec4 b)
+{
+  a = vec4(a.xy, a.xy + a.zw);
+  b = vec4(b.xy, b.xy + b.zw);
+  vec4 result = vec4(max(a.xy, b.xy), min(a.zw, b.zw));
+  if (any (greaterThanEqual (result.xy, result.zw)))
+    return vec4(0.0,0.0,0.0,0.0);
+  return vec4(result.xy, result.zw - result.xy);
+}
+
+void main() {
+  vec4 rect = intersect(inRect, push.clip_bounds);
+
+  vec2 pos = rect.xy + rect.zw * offsets[gl_VertexIndex];
+  gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
+  outColor = inColor;
+}
diff --git a/gsk/resources/vulkan/color-clip.vert.spv b/gsk/resources/vulkan/color-clip.vert.spv
new file mode 100644 (file)
index 0000000..0089004
Binary files /dev/null and b/gsk/resources/vulkan/color-clip.vert.spv differ
index 98c661da196d9fb6819892653850c52c56461dc9..29bbae9dfd0753ec73d49efa0eefb8c71d069d59 100644 (file)
Binary files a/gsk/resources/vulkan/color.frag.spv and b/gsk/resources/vulkan/color.frag.spv differ